# -*- coding: utf-8 -*-
import logging
import time
from traceback import format_exc
from selenium import webdriver
from scrapy.utils.project import get_project_settings
from selenium.webdriver.support.select import Select
from zc_core.dao.cookie_dao import CookieDao

logger = logging.getLogger('login')


class SeleniumLogin(object):
    # 登录地址
    login_url = 'http://mall.plap.cn/users/sign_in.html'
    index_url = 'http://mall.plap.cn/'
    cookie_key_filter = ['_session_id']

    def __init__(self, timeout=60):
        settings = get_project_settings()
        self.max_login_retry = settings.get('MAX_LOGIN_RETRY', 1)
        self.timeout = timeout
        self.option = webdriver.ChromeOptions()
        # self.option.add_argument('--headless')
        self.option.add_argument('--no-sandbox')
        self.accounts = settings.get('ACCOUNTS', [])

    def new_chrome(self):
        self.browser = webdriver.Chrome(chrome_options=self.option)
        self.browser.set_window_size(1400, 900)
        self.browser.set_page_load_timeout(self.timeout)

    def login(self, login_type):
        try:
            self.new_chrome()
            self.browser.get(self.login_url)
            time.sleep(2)
            self.browser.refresh()
            time.sleep(3)
            self.browser.refresh()
            time.sleep(3)
            self.browser.refresh()
            time.sleep(3)

            account = {}
            if login_type == 'spu':
                account = self.accounts[0]
            elif login_type == 'full':
                account = self.accounts[1]
            elif login_type == 'sale':
                account = self.accounts[1]
            elif login_type == 'material':
                account = self.accounts[1]

            logger.info('login account: %s' % account)

            Select(self.browser.find_element_by_id("login_type")).select_by_value('2')
            time.sleep(1)

            username = self.browser.find_element_by_id("user_loginname")
            username.clear()
            username.send_keys(account.get('acc'))
            time.sleep(1)

            password = self.browser.find_element_by_id("user_password")
            password.clear()
            password.send_keys(account.get('pwd'))
            time.sleep(1)

            # 登录
            btn = self.browser.find_element_by_class_name("login-button")
            btn.click()
            time.sleep(10)

            # 尝试主动加载首页
            self.browser.get(self.index_url)
            time.sleep(2)

            # 校验
            cookies = ''
            if '您好，供应商' in self.browser.page_source:
                cookies = self.browser.get_cookies()
                logger.info('--> cookies: %s' % cookies)

            self.browser.close()
            return cookies
        except Exception as e:
            _ = e
            logger.error(format_exc())
            self.browser.close()
            return list()

    # cookie获取
    def get_cookies(self, login_type):
        settings = get_project_settings()
        key = 'zc:cookie:{}:{}'.format(settings.get('BOT_NAME'), login_type)
        cookie_dao = CookieDao()
        cookies = cookie_dao.get_cookie(key=key)
        if not cookies:
            cookies = self.__get_cookies(0, login_type)
            cookie_dao.save_cookie(cookies=cookies, key=key, expire_time=14400)
        return cookies

    # 最大重试登录获取cookie
    def __get_cookies(self, retry, login_type):
        # 登录获取
        arr = self.login(login_type)
        if not arr:
            # 失败重试
            if retry <= self.max_login_retry:
                retry = retry + 1
                logger.info('--> 登录失败重试: %s次' % retry)
                return self.__get_cookies(retry, login_type)
            else:
                logger.info('--> 放弃失败重试: %s次' % retry)
                return dict()

        # 重组
        cookies = dict()
        for cookie in arr:
            # 敏感过滤
            if cookie.get('name') and cookie.get('name') in self.cookie_key_filter:
                cookies[cookie.get('name')] = cookie.get('value')

        # 校验
        if not cookies or not self._validate_cookie(cookies):
            # 失败重试
            if retry <= self.max_login_retry:
                retry = retry + 1
                logger.info('--> 登录失败重试: %s次' % retry)
                return self.__get_cookies(retry, login_type)
            else:
                logger.info('--> 放弃失败重试: %s次' % retry)
                return dict()

        logger.info('--> 登录成功: %s次' % retry)
        return cookies

    # cookie校验
    def _validate_cookie(self, cookies):
        # 必要字段
        if cookies and '_session_id' in cookies and cookies.get('_session_id'):
            return True
        return False